<template>
  <div class="workflow-editor-container" :class="{ 'readonly-mode': readonly }">
    <!-- 工具栏 (只读模式下隐藏编辑功能) -->
    <Toolbar
      v-if="!readonly"
      :edit-mode="editMode"
      :save-button-text="saveButtonText"
      @change-mode="handleChangeMode"
      @validate="handleValidate"
      @clear="handleClear"
      @zoom-in="handleZoomIn"
      @zoom-out="handleZoomOut"
      @fit-view="handleFitView"
      @export="handleExport"
      @import="handleImport"
      @save="handleSave"
    />

    <!-- 只读模式下的简化工具栏 -->
    <div v-else class="readonly-toolbar">
      <div class="toolbar-actions">
        <el-button size="small" @click="handleZoomIn">
          <el-icon><ZoomIn /></el-icon>
          放大
        </el-button>
        <el-button size="small" @click="handleZoomOut">
          <el-icon><ZoomOut /></el-icon>
          缩小
        </el-button>
        <el-button size="small" @click="handleFitView">
          <el-icon><FullScreen /></el-icon>
          适应窗口
        </el-button>
      </div>
    </div>

    <!-- 编辑区域 -->
    <div class="editor-content">
      <!-- 可视化编辑模式 -->
      <template v-if="editMode === 'visual'">
        <!-- 节点库 (只读模式下隐藏) -->
        <NodePanel v-if="!readonly" />

        <!-- 画布 -->
        <div class="canvas-wrapper" :class="{ 'readonly-canvas': readonly }">
          <WorkflowCanvas
            ref="canvasRef"
            v-model="workflowData"
            :readonly="readonly"
            @node-selected="handleNodeSelected"
            @edge-selected="handleEdgeSelected"
          />
        </div>

        <!-- 属性面板 (只读模式下隐藏) -->
        <PropertyPanel
          v-if="!readonly"
          :selected-node="selectedNode"
          @update-node="handleUpdateNode"
          @delete-node="handleDeleteNode"
        />
      </template>

      <!-- YAML编辑模式 -->
      <template v-else>
        <div class="yaml-editor-wrapper">
          <YamlEditor
            v-model="yamlContent"
            :height="600"
            :readonly="readonly"
          />
        </div>
      </template>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, computed, onMounted, nextTick, provide } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useVueFlow } from '@vue-flow/core'
import yaml from 'js-yaml'
import Toolbar from './Toolbar.vue'
import NodePanel from './NodePanel.vue'
import WorkflowCanvas from './WorkflowCanvas.vue'
import PropertyPanel from './PropertyPanel.vue'
import YamlEditor from '../YamlEditor/index.vue'
import { validateNodeConfig } from './nodeTypes'

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({ nodes: [], edges: [] })
  },
  readonly: {
    type: Boolean,
    default: false
  },
  saveButtonText: {
    type: String,
    default: '保存'
  }
})

const emit = defineEmits(['update:modelValue', 'save'])

const editMode = ref('visual')
const workflowData = ref({
  nodes: props.modelValue.nodes || [],
  edges: props.modelValue.edges || []
})
const yamlContent = ref('')
const selectedNode = ref(null)
const selectedEdge = ref(null)
const canvasRef = ref(null)

// 将工作流数据提供给子组件（用于变量引用功能）
provide('workflowData', workflowData)

// 同步到YAML
const syncToYaml = () => {
  try {
    const yamlData = {
      nodes: workflowData.value.nodes.map(node => ({
        id: node.id,
        type: node.type,
        name: node.data?.label || node.type,
        config: node.data?.config || {},
        position: node.position
      })),
      edges: workflowData.value.edges.map(edge => ({
        id: edge.id,
        source: edge.source,
        target: edge.target
      }))
    }
    yamlContent.value = yaml.dump(yamlData)
  } catch (error) {
    console.error('转换为YAML失败:', error)
  }
}

// 从YAML同步
const syncFromYaml = () => {
  try {
    const data = yaml.load(yamlContent.value)
    if (data && data.nodes) {
      workflowData.value = {
        nodes: data.nodes.map(node => {
          // 确保 config 是对象类型,而不是数组
          let safeConfig = {}
          if (node.config && typeof node.config === 'object' && !Array.isArray(node.config)) {
            safeConfig = node.config
          } else if (node.config) {
            console.warn('Node config is not a plain object, using empty object', node.config)
          }

          return {
            id: node.id,
            type: node.type,
            position: node.position || { x: 0, y: 0 },
            data: {
              label: node.name,
              config: safeConfig
            }
          }
        }),
        edges: data.edges || []
      }
    }
  } catch (error) {
    ElMessage.error('YAML格式错误,请检查')
    console.error('解析YAML失败:', error)
  }
}

// 防止递归更新的标志
const isUpdatingFromProps = ref(false)

// 监听工作流数据变化
watch(workflowData, (newVal) => {
  if (!isUpdatingFromProps.value) {
    emit('update:modelValue', newVal)
    // 同步更新YAML内容
    if (editMode.value === 'visual') {
      syncToYaml()
    }
  }
}, { deep: true })

// 监听props变化
watch(() => props.modelValue, (newVal) => {
  if (newVal && !isUpdatingFromProps.value) {
    isUpdatingFromProps.value = true
    workflowData.value = {
      nodes: newVal.nodes || [],
      edges: newVal.edges || []
    }
    if (editMode.value === 'visual') {
      syncToYaml()
    }
    nextTick(() => {
      isUpdatingFromProps.value = false
    })
  }
}, { deep: true })

// 切换编辑模式
const handleChangeMode = (mode) => {
  if (mode === 'yaml' && editMode.value === 'visual') {
    // 从可视化切换到YAML
    syncToYaml()
  } else if (mode === 'visual' && editMode.value === 'yaml') {
    // 从YAML切换到可视化
    syncFromYaml()
  }
  editMode.value = mode
}

// 校验工作流
const handleValidate = () => {
  const errors = []

  // 检查是否有节点
  if (workflowData.value.nodes.length === 0) {
    errors.push('工作流中至少需要一个节点')
  }

  // 校验每个节点
  workflowData.value.nodes.forEach(node => {
    const validation = validateNodeConfig(node)
    if (!validation.valid) {
      const nodeLabel = node.data?.label || node.type || node.id
      errors.push(`节点 "${nodeLabel}" (${node.id}): ${validation.errors.join(', ')}`)
    }
  })

  // 检查孤立节点
  const connectedNodes = new Set()
  workflowData.value.edges.forEach(edge => {
    connectedNodes.add(edge.source)
    connectedNodes.add(edge.target)
  })

  if (workflowData.value.nodes.length > 1) {
    workflowData.value.nodes.forEach(node => {
      if (!connectedNodes.has(node.id)) {
        const nodeLabel = node.data?.label || node.type || node.id
        errors.push(`节点 "${nodeLabel}" (${node.id}) 未连接`)
      }
    })
  }

  if (errors.length > 0) {
    ElMessage.error({
      message: `发现 ${errors.length} 个问题:\n${errors.join('\n')}`,
      duration: 5000,
      showClose: true
    })
    return false
  } else {
    ElMessage.success('工作流校验通过')
    return true
  }
}

// 清空画布
const handleClear = async () => {
  try {
    await ElMessageBox.confirm('确定要清空画布吗？此操作不可恢复。', '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    workflowData.value = {
      nodes: [],
      edges: []
    }
    selectedNode.value = null
    selectedEdge.value = null
    ElMessage.success('画布已清空')
  } catch (error) {
    // 用户取消
  }
}

// 放大
const handleZoomIn = () => {
  // Zoom functionality will be handled through VueFlow instance in canvas
  try {
    const vueFlowInstance = useVueFlow('workflow-canvas')
    if (vueFlowInstance) {
      vueFlowInstance.zoomIn()
    }
  } catch (error) {
    console.warn('Unable to zoom in:', error)
  }
}

// 缩小
const handleZoomOut = () => {
  // Zoom functionality will be handled through VueFlow instance in canvas
  try {
    const vueFlowInstance = useVueFlow('workflow-canvas')
    if (vueFlowInstance) {
      vueFlowInstance.zoomOut()
    }
  } catch (error) {
    console.warn('Unable to zoom out:', error)
  }
}

// 适应画布
const handleFitView = () => {
  // Fit view functionality will be handled through VueFlow instance in canvas
  try {
    const vueFlowInstance = useVueFlow('workflow-canvas')
    if (vueFlowInstance) {
      vueFlowInstance.fitView()
    }
  } catch (error) {
    console.warn('Unable to fit view:', error)
  }
}

// 导出
const handleExport = () => {
  try {
    const dataStr = yaml.dump({
      nodes: workflowData.value.nodes,
      edges: workflowData.value.edges
    })
    const blob = new Blob([dataStr], { type: 'text/yaml' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `workflow-${Date.now()}.yaml`
    a.click()
    URL.revokeObjectURL(url)
    ElMessage.success('工作流已导出')
  } catch (error) {
    ElMessage.error('导出失败')
    console.error('导出失败:', error)
  }
}

// 导入
const handleImport = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.yaml,.yml'
  input.onchange = (e) => {
    const file = e.target.files[0]
    if (!file) return

    const reader = new FileReader()
    reader.onload = (event) => {
      try {
        const data = yaml.load(event.target.result)
        if (data && data.nodes) {
          // 确保导入的节点配置是正确的格式
          const sanitizedNodes = data.nodes.map(node => {
            let safeConfig = {}
            if (node.data?.config && typeof node.data.config === 'object' && !Array.isArray(node.data.config)) {
              safeConfig = node.data.config
            } else if (node.config && typeof node.config === 'object' && !Array.isArray(node.config)) {
              safeConfig = node.config
            } else if (node.data?.config || node.config) {
              console.warn('Imported node has invalid config format, using empty object')
            }

            return {
              ...node,
              data: {
                ...(node.data || {}),
                config: safeConfig
              }
            }
          })

          workflowData.value = {
            nodes: sanitizedNodes,
            edges: data.edges || []
          }
          ElMessage.success('工作流已导入')
        } else {
          ElMessage.error('文件格式不正确')
        }
      } catch (error) {
        ElMessage.error('文件解析失败')
        console.error('导入失败:', error)
      }
    }
    reader.readAsText(file)
  }
  input.click()
}

// 转换为后端期望的格式
const convertToBackendFormat = (data) => {
  // 构建边的映射：source -> target
  const nextMap = new Map()
  if (data.edges && Array.isArray(data.edges)) {
    data.edges.forEach(edge => {
      // 每个节点只保留第一个 next（后端设计限制）
      if (!nextMap.has(edge.source)) {
        nextMap.set(edge.source, edge.target)
      }
    })
  }

  // 转换节点格式
  const nodes = (data.nodes || []).map(node => {
    return {
      id: node.id,
      type: node.type,
      name: node.data?.label || node.type,
      config: node.data?.config || {},
      next: nextMap.get(node.id) || null
    }
  })

  return { nodes }
}

// 保存
const handleSave = () => {
  if (editMode.value === 'yaml') {
    syncFromYaml()
  }

  if (handleValidate()) {
    // 转换为后端期望的格式
    const backendFormat = convertToBackendFormat(workflowData.value)
    emit('save', backendFormat)
  }
}

// 节点选中
const handleNodeSelected = (node) => {
  selectedNode.value = node
  selectedEdge.value = null
}

// 边选中
const handleEdgeSelected = (edge) => {
  selectedEdge.value = edge
  selectedNode.value = null
}

// 更新节点
const handleUpdateNode = ({ id, data }) => {
  if (canvasRef.value) {
    canvasRef.value.updateNode(id, data)
  }
}

// 删除节点
const handleDeleteNode = (nodeId) => {
  if (canvasRef.value) {
    canvasRef.value.deleteNode(nodeId)
    selectedNode.value = null
  }
}

defineExpose({
  validate: handleValidate,
  getWorkflowData: () => workflowData.value
})
</script>

<style lang="scss" scoped>
.workflow-editor-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #f5f7fa;

  .readonly-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    background: white;
    border-bottom: 1px solid #e4e7ed;

    .toolbar-title {
      font-size: 16px;
      font-weight: 600;
      color: #303133;
    }

    .toolbar-actions {
      display: flex;
      gap: 8px;
    }
  }

  .editor-content {
    flex: 1;
    display: flex;
    overflow: hidden;

    .canvas-wrapper {
      flex: 1;
      position: relative;

      &.readonly-canvas {
        width: 100%;
      }
    }

    .yaml-editor-wrapper {
      flex: 1;
      padding: 20px;
      background: white;
    }
  }

  &.readonly-mode {
    .editor-content {
      .canvas-wrapper {
        flex: 1;
      }
    }
  }
}
</style>
